Skip to content

feat: Add AI helpers to Javascript and Queries - #41590

Closed
salevine wants to merge 44 commits into
releasefrom
feat/enable-ai
Closed

feat: Add AI helpers to Javascript and Queries#41590
salevine wants to merge 44 commits into
releasefrom
feat/enable-ai

Conversation

@salevine

@salevine salevine commented Mar 3, 2026

Copy link
Copy Markdown
Contributor

Description

Slack Thread

Add AI helpers to JavaScript modules and queries, with a configurable AI assistant admin panel supporting multiple providers.

Summary

  • Global AI side panel architecture with ongoing chat and conversation history
  • Support for Claude, OpenAI, Azure OpenAI, and Local LLM (Ollama) providers
  • AI admin settings page with connection testing, model selection, and context size presets
  • Azure OpenAI: configurable API version and max completion tokens fields
  • AI reference service for enhanced system prompts with external file customization
  • SSRF protection for LLM connections

Test plan

  • Select each AI provider and verify settings save/load correctly
  • Test Azure OpenAI with GPT-5.2 deployment — verify configurable API version and max tokens work
  • Test "Test Key" button for each provider
  • Test Local LLM connection with Ollama — verify model auto-detection
  • Open AI panel in JS editor and verify conversation flow
  • Verify AI panel clears context when switching editors

Fixes #Issue Number

Automation

/ok-to-test tags=""

Communication

Should the DevRel and Marketing teams inform users about this change?

  • Yes
  • No

Warning

Tests have not run on the HEAD e40490c yet


Thu, 26 Mar 2026 18:06:04 UTC

Summary by CodeRabbit

  • New Features

    • AI Assistant added to editors (Ask AI button, editor side panels, global AI panel) with multi-provider support and quick actions.
    • Admin AI Settings page to configure providers, keys, local LLMs, test connections, and fetch models.
    • MSSQL read-only connection support; MCP datasource plugin plan introduced.
  • Documentation

    • New AI reference guides (JavaScript, SQL, GraphQL), project guide, prompts reference, and security audit/fixes documentation.

Note

Medium Risk
Adds new organization-level AI configuration endpoints and a new AI-assistant request API that proxies calls to LLM providers, which impacts security-sensitive config handling and introduces new UI/Redux flows across editors.

Overview
Introduces an AI Assistant for JavaScript and query editors with new side-panel UIs (editor-scoped and global), quick actions, chat history, and code insertion/apply flows, backed by new Redux actions/state (aiAssistantReducer).

Adds organization-level AI configuration support: a new Admin Settings “AI Assistant” page plus client OrganizationApi methods and server /ai-config endpoints to store provider settings/keys, test API keys, test local LLM connectivity, and fetch local model lists.

Adds a server-side POST /users/ai-assistant/request endpoint and client UserApi.requestAIResponse (with long timeout) so the frontend requests AI responses via the Appsmith server, along with assorted repo tooling/docs updates (Claude/Cursor rules, security audit writeups, gitignore tweaks).

Written by Cursor Bugbot for commit 270472a. This will update automatically on new commits. Configure here.

salevine and others added 23 commits January 26, 2026 23:53
…n testing

- Add AI Settings page at /settings/ai with provider selection (Claude, OpenAI, Local LLM)
- Add LOCAL_LLM enum to AIProvider
- Add localLlmUrl and localLlmContextSize fields to OrganizationConfiguration
- Add Test Connection button for Local LLM that validates:
  - URL parsing and format
  - DNS resolution with resolved IP display
  - TCP connection to host:port
  - TLS handshake (for HTTPS)
  - HTTP response and endpoint validation
  - Checks if response looks like an LLM API (JSON with expected fields)
  - Shows actual response preview from the server
- Add Test Key button for Claude and OpenAI that:
  - Sends a real test request to verify API key works
  - Shows step-by-step diagnostics
  - Displays the AI response on success
  - Shows detailed error info and suggestions on failure
- Fix GPT component to use styled textarea instead of missing Textarea export
- Fix response interceptor handling in AI Settings page

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ling fixes

- Add AISidePanel component with quick actions (Explain, Fix Errors, Refactor, Add Comments)
- Add AIEditorLayout for side-by-side editor + AI panel integration
- Fix response extraction in sagas to handle both axios wrapped and interceptor unwrapped formats
- Add context detection: JS mode uses AST to find current function, SQL/GraphQL uses cursor window
- Fix icon names to use valid Appsmith design system icons
- Enable AI for JavaScript, SQL, and GraphQL editor modes in DynamicTextField

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Removed import of getJSFunctionLocationFromCursor from pages/Editor/JSEditor/utils
which was creating a cyclic dependency chain. Now using a simple window-based
approach for JavaScript context (same as SQL/GraphQL) - 15 lines before/after cursor.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When the AI response contains code blocks without a language specifier,
use the current editor mode (SQL, GraphQL, etc.) instead of always
defaulting to JavaScript.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added CLEAR_AI_RESPONSE action to reset lastResponse and error when
the editor mode changes. This prevents AI responses from one editor
(e.g., JS) from persisting when switching to another editor (e.g., SQL).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change Redux state from lastResponse to messages array for multi-turn chat
- Pass conversation history to Claude/OpenAI APIs for context-aware responses
- Add chat-style UI with message bubbles and auto-scroll
- Add clear chat button and green toggle for enabled state
- Create AIMessageDTO for backend conversation history support
- Simplify EE files to re-export from CE where possible

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rename "Appsmith AI Beta" to "Ask AI" in slash command menu
- Remove beta flag from Ask AI command
- Add Redux state and actions for AI panel open/close
- Wire slash command to dispatch OPEN_AI_PANEL action
- CodeEditor syncs Redux state to open panel when triggered

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Increase the number of lines sent to AI for context:
- JavaScript: 15 -> 50 lines before/after cursor
- SQL: 10 -> 40 lines before/after cursor
- GraphQL: 10 -> 40 lines before/after cursor (EE only)
- JSON: 10 -> 40 lines before/after cursor (EE only)

This helps the AI better understand larger code structures when
providing assistance.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create AIReferenceService to load mode-specific reference documentation
- Add reference files for JavaScript, SQL, GraphQL, and common issues
- Implement three-tier fallback: external path -> bundled -> inline
- Update AIAssistantServiceCEImpl to use dynamic prompts
- Increase max_tokens from 4096 to 8192 for longer responses
- Increase response truncation from 100K to 200K chars
- Add appsmith.ai.references.path configuration property

The reference files contain Appsmith-specific patterns, best practices,
and common issues to help the AI provide more accurate, context-aware
responses.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Documents how users can customize AI reference files:
- Docker volume mount
- Docker Compose
- Kubernetes ConfigMap
- Environment variable for custom path
- File format guidelines
- Fallback behavior explanation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace per-editor AI panels with single global side panel
- Add GlobalAISidePanel component with scrollable responses and resizable input
- Update CodeEditor to dispatch openAIPanelWithContext action
- Add editor context tracking (mode, entity, cursor position)
- Auto-close panel on route navigation
- Fix AI selector state path and add missing reducer properties
- Add quick actions (Explain, Fix Errors, Refactor, Add Comments)
- Support conversation history display with code block rendering

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add getReferenceFilesInfo() method to AIReferenceService to detect
  whether external files are being used instead of bundled defaults
- Show "Custom AI Context Files Active" notice on AI Configuration page
  when external reference files are detected
- Refactor AI settings page with reusable TestResultDisplay and
  ApiKeyTestResult components, reducing code duplication

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…rotection

- Add model dropdown that auto-fetches available models after successful connection test
- Add context size preset buttons (4K, 8K, 16K, 32K, 128K) with custom input option
- Add POST /ai-config/fetch-models endpoint to query Ollama's /api/tags
- Add localLlmModel field to AIConfigDTO and OrganizationConfigurationCE
- Fix SSRF vulnerabilities by using WebClientUtils with IP filtering
- Block requests to internal IPs and cloud metadata endpoints (169.254.169.254)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…sage visibility

- Clear AI messages when switching between editor contexts (JS to Query)
- Fix user message bubble contrast by using subtle background with border
- Add security audit document to gitignore

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Summary of fixes:

- Fix Ollama connection: properly construct /api/chat URL when admin
  provides a base URL (e.g. http://localhost:11434) instead of the
  full endpoint path

- Fix request timeouts: increase Axios timeout from 20s to 180s for
  AI requests, and increase nginx proxy_read_timeout to 180s, since
  LLM model loading (cold start) can take 60-90+ seconds

- Add Microsoft Copilot (Azure OpenAI) support: new copilotEndpoint
  field in AI config, dedicated callCopilotAPI method, and admin UI
  for configuring the Azure OpenAI endpoint URL

- Bypass SSRF protection for admin-configured LLM endpoints: create
  custom WebClient instances for LOCAL_LLM and COPILOT providers to
  avoid blocking localhost/private network requests

- Improve error messages: surface actual error details instead of
  generic "Failed to get AI response", with specific messages for
  timeout, connection refused, model not found, and auth errors

- Add "Clear Chat" button to Quick Actions in all AI panels (CE and
  EE AISidePanel, GlobalAISidePanel) so users can easily clear the
  conversation history

- Fix Ollama test connection: use GET /api/tags instead of POST to
  avoid 404 when testing connection without a specific model

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolve conflicts by keeping both AI assistant and favorites features
in sagas, controllers, and service layers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the "MS Copilot" AI provider with "Azure OpenAI" across the full
stack. Users now provide endpoint, deployment name, and API key — the
system constructs the Azure OpenAI URL internally. Existing COPILOT
configurations are migrated at read time with no DB migration needed.

Backend: add AZURE_OPENAI enum, domain fields, real API test endpoint,
and URL construction in AI service. Frontend: new 3-field config form,
updated provider dropdown, save/load/test logic.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…OpenAI

Azure OpenAI newer models (GPT-5.2, o1, o3) require max_completion_tokens
instead of max_tokens and a specific api-version query parameter. Both were
previously hardcoded. This adds them as configurable fields in the AI admin
settings UI with sensible defaults (api-version: 2024-12-01-preview,
max_completion_tokens: 16384).

Also removes hardcoded temperature from Azure requests (unsupported by
reasoning models) and adds error body logging for Azure API failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@salevine
salevine requested a review from sharat87 as a code owner March 3, 2026 18:01
@salevine salevine added the Enhancement New feature or request label Mar 3, 2026
@salevine
salevine requested a review from abhvsn as a code owner March 3, 2026 18:01
@salevine salevine added the Enhancement New feature or request label Mar 3, 2026
@coderabbitai

coderabbitai Bot commented Mar 3, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds an AI assistant feature: frontend UI and Redux flows, sagas calling new APIs, backend controllers/services for multi-provider LLM integration, DTOs and domain fields, migration to add org flag, AI reference resources and admin settings, plus extensive documentation and security/audit artifacts.

Changes

Cohort / File(s) Summary
Documentation & Planning
\.cursor/rules/..., cursorrules, CLAUDE.md, AI_ADMIN_CONTROL_ANALYSIS.md, SECURITY_*.md, SERVER_SIDE_PROXY_PLAN.md, docs/AI_PROMPTS_REFERENCE.md, .cursor/plans/*, .claude/*
New project guides, security audits, implementation plans, prompt references, and tooling hooks. Pure documentation and planning artifacts.
Frontend — Redux & Sagas
app/client/src/ce/actions/aiAssistantActions.ts, app/client/src/ce/reducers/aiAssistantReducer.ts, app/client/src/ce/selectors/aiAssistantSelectors.ts, app/client/src/ce/sagas/AIAssistantSagas.ts, app/client/src/ce/constants/ReduxActionConstants.tsx, app/client/src/ce/sagas/index.tsx, app/client/src/ce/reducers/index.tsx
New AI action creators, reducer, selectors, saga listeners for fetching AI responses and loading AI settings; constants and root saga/reducer registration added.
Frontend — UI Components & Integration
app/client/src/ce/components/.../GPT/*, app/client/src/ce/components/.../GlobalAISidePanel/*, app/client/src/ee/components/.../GPT/*, app/client/src/components/editorComponents/CodeEditor/*, app/client/src/components/editorComponents/form/*, app/client/src/ce/components/.../AskAIButton.tsx
Adds AISidePanel, GlobalAISidePanel, AIEditorLayout, AskAIButton, trigger/context logic, code insertion actions, quick prompts, and editor integration; mode-aware context extraction and UI wiring.
Frontend — API, Admin & Pages
app/client/src/ce/api/OrganizationApi.ts, app/client/src/ce/api/UserApi.tsx, app/client/src/pages/AdminSettings/AI/*, app/client/src/ce/pages/AdminSettings/config/*, app/client/src/pages/AppIDE/layouts/*, app/client/src/sagas/ActionSagas.ts
Client API methods for AI config, model fetching, test endpoints; Admin AISettings page and config registration; layout inclusion of GlobalAISidePanel; action saga changes to open AI panel.
Backend — Services & Reference Loading
app/server/.../services/ce/AIAssistantServiceCEImpl.java, app/server/.../services/AIAssistantServiceCE.java, app/server/.../services/ce/AIReferenceServiceCEImpl.java, app/server/.../services/ce/AIReferenceServiceCE.java, app/server/.../services/AIReferenceService.java, app/server/.../services/AIReferenceServiceImpl.java
New CE AI assistant implementation supporting multiple providers (LOCAL_LLM, AZURE_OPENAI, COPILOT, CLAUDE, OPENAI), prompt/response handling, and reference-content service with fallback and caching.
Backend — Controllers, DTOs & Enums
app/server/.../controllers/ce/OrganizationControllerCE.java, app/server/.../controllers/ce/UserControllerCE.java, app/server/.../controllers/OrganizationController.java, app/server/.../controllers/UserController.java, app/server/.../dtos/AI*.java, app/server/.../domains/AIProvider.java
New endpoints for AI config CRUD, testing, model fetch; POST /ai-assistant/request endpoint; DTOs for config, editor context, messages, requests; AIProvider enum; controller constructors updated for new dependencies.
Backend — Domain & Migration
app/server/.../domains/ce/OrganizationConfigurationCE.java, app/server/.../migrations/db/ce/Migration075AddIsAIAssistantEnabledToOrganizationConfiguration.java
OrganizationConfiguration extended with AI provider keys, endpoints, enable flag and related fields; migration adds isAIAssistantEnabled with safe defaults.
Backend — Resources & Config
app/server/.../resources/ai-references/*, app/server/.../resources/application-ce.properties, .gitignore
Added AI reference markdowns (javascript/sql/graphql/common issues), README, application property for references path, and gitignore entry for an audit PDF.
Misc — Plugin/Plans/Other
.cursor/plans/*, FixMSSQLReadOnly.md, app/client/.../ce/sagas/userSagas.tsx
Various planning docs, MCP plugin plan, MSSQL read-only note, small saga null-safety tweak.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Client as Frontend UI
    participant Redux as Redux State
    participant Saga as AI Saga
    participant API as Client API
    participant Server as Backend Controller/Service
    participant Provider as LLM Provider

    User->>Client: open panel / send prompt
    Client->>Redux: dispatch FETCH_AI_RESPONSE
    Redux->>Saga: saga handles FETCH_AI_RESPONSE
    Saga->>API: POST /v1/users/ai-assistant/request (AIRequestDTO)
    API->>Server: request forwarded to UserControllerCE.requestAIResponse
    Server->>Server: validate + route to AIAssistantServiceCEImpl
    Server->>Provider: provider-specific HTTP call (OpenAI/Claude/Azure/Local)
    Provider-->>Server: LLM response
    Server->>Server: extract/truncate/format response
    Server-->>API: return response payload
    API-->>Saga: response received
    Saga->>Redux: dispatch FETCH_AI_RESPONSE_SUCCESS
    Redux->>Client: state updates -> render response (code blocks, actions)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🤖✨ Panels slide, prompts take flight,
Redux holds whispers through the night,
Java routes and providers align,
Code blocks copy, editors shine,
An assistant lands — helpful, bright.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/enable-ai

@salevine

salevine commented Mar 3, 2026

Copy link
Copy Markdown
Contributor Author

/build-deploy-preview skip-tests=true

@github-actions

github-actions Bot commented Mar 3, 2026

Copy link
Copy Markdown

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/22636345472.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 41590.
recreate: .

The AI Assistant was generating generic SQL queries because the
datasource schema was never proactively fetched — it only read from
the Redux cache which is empty until the user manually browses the
schema tab. Now enrichContextWithSchema dispatches
fetchDatasourceStructure and waits for the result before proceeding.

The AskAIButton was visible in every CodeEditor (including API editor
JSON fields) because it only checked a global Redux flag, bypassing
the mode-based isAIEnabled gate. Now the button is gated by
this.AIEnabled. Also removed isJSONMode from DynamicTextField's
AIAssisted computation for consistency.
@subrata71

Copy link
Copy Markdown
Collaborator

/build-deploy-preview skip-tests=true

@github-actions

Copy link
Copy Markdown

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/23048181902.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 41590.
recreate: .
base-image-tag: .

- Fix TS2769 in AIAssistantSagas: use inline type for take()
  predicates instead of ReduxAction<T> which is incompatible with
  redux-saga's Predicate<Action<string>>
- Fix prettier violations in aiSchemaSerializer.ts: collapse
  multi-line RegExp constructors to single lines
- Fix restricted-import lint error: create EE re-export for
  ce/components/editorComponents/GPT/shared and update imports
  in GlobalAISidePanel and EE AISidePanel to use ee/ path
@subrata71

Copy link
Copy Markdown
Collaborator

/build-deploy-preview skip-tests=true

@github-actions

Copy link
Copy Markdown

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/23052520196.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 41590.
recreate: .
base-image-tag: .

@github-actions

Copy link
Copy Markdown

Deploy-Preview-URL: https://ce-41590.dp.appsmith.com

@salevine
salevine requested a review from riodeuno as a code owner March 18, 2026 20:48
@salevine

Copy link
Copy Markdown
Contributor Author

/build-deploy-preview skip-tests=true

@github-actions

Copy link
Copy Markdown

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/23267426495.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 41590.
recreate: .
base-image-tag: .

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
salevine and others added 2 commits March 18, 2026 17:30
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Import Components type from react-markdown and use Partial<Components>
to properly type MARKDOWN_COMPONENTS, removing the incompatible
Record<string, unknown> index signature.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@salevine

Copy link
Copy Markdown
Contributor Author

/build-deploy-preview skip-tests=true

@github-actions

Copy link
Copy Markdown

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/23269649542.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 41590.
recreate: .
base-image-tag: .

@github-actions

Copy link
Copy Markdown

Deploy-Preview-URL: https://ce-41590.dp.appsmith.com

Scope inline code styling (background, padding, border-radius) to only
code elements not inside pre blocks, preventing the light background
from bleeding into dark-themed fenced code blocks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@salevine

Copy link
Copy Markdown
Contributor Author

/build-deploy-preview skip-tests=true

@github-actions

Copy link
Copy Markdown

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/23273899909.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 41590.
recreate: .
base-image-tag: .

@github-actions

Copy link
Copy Markdown

Deploy-Preview-URL: https://ce-41590.dp.appsmith.com

@github-actions

Copy link
Copy Markdown

Failed server tests

  • com.appsmith.server.git.ServerSchemaMigrationEnforcerTest#saveGitRepo_ImportAndThenExport_diffOccurs

@github-actions

Copy link
Copy Markdown

Failed server tests

  • com.appsmith.server.helpers.GitUtilsTest#isRepoPrivate

@github-actions

Copy link
Copy Markdown

This PR has not seen activitiy for a while. It will be closed in 7 days unless further activity is detected.

@github-actions github-actions Bot added the Stale label Mar 26, 2026
@github-actions

github-actions Bot commented Apr 3, 2026

Copy link
Copy Markdown

This PR has been closed because of inactivity.

@github-actions github-actions Bot closed this Apr 3, 2026
salevine added a commit that referenced this pull request Aug 4, 2026
## Description

**TL;DR** — Ask AI (AI-assisted code editing in the JS/query editors,
plus an admin page to configure the AI provider) currently exists only
in the enterprise edition. Nothing about it is actually
enterprise-specific, so this brings it to CE. The code is ported from
`appsmith-ee/release` unchanged where it already lives in `ce` packages,
and moved from `src/ee` into `src/ce` where it does not.

### Background

Ask AI was originally built for CE on `feat/enable-ai` (PR #41590). That
PR was handed over for review in March, went quiet, and was closed by
the stale bot on 2026-04-03 without ever being merged. The feature
instead shipped in the enterprise repo as `appsmith-ee#8845`, and CE
received only inert stubs via #41692 —
`ce/selectors/aiAssistantSelectors.ts` and friends returning `null` /
`false` / `[]`.

That split was not driven by any technical requirement:

- `ee/selectors/aiAssistantSelectors.ts` contains **no license or
entitlement check** — it reads `state.aiAssistant` and nothing else.
- Enablement is ordinary organization configuration
(`AIAssistantConfig.isAIAssistantEnabled`), set by an instance admin.
- The feature flag that once gated it was removed wholesale in
`appsmith-ee#9119`.

The enterprise-only placement was a product decision, and this PR
reverses it.

### Why port from EE rather than revive the original branch

`feat/enable-ai` is four months stale and EE has since reworked the
implementation:

| | `feat/enable-ai` | `appsmith-ee/release` |
|---|---|---|
| AI settings storage | flat fields on `OrganizationConfiguration` |
nested `AIAssistantConfig` document |
| Provider dispatch | inline `if` chain | extracted `dispatchToProvider`
|
| Datasource schema enrichment | client-side | server-side
`AiDatasourceSchemaSerializerCE` |
| `/ai-config` endpoints | ~1450 lines inlined into
`OrganizationControllerCE` | dedicated `AIConfigControllerCE` +
`AIConfigServiceCE` |
| `AIReferenceServiceCEImpl` | 239 lines | 107 lines |

Reviving the branch would land a divergent second implementation and
guarantee a conflict with the community sync. Porting EE's current
version starts CE and EE byte-identical on the `ce`-package files. Note
the security commit and the review fixes on top of it deliberately move
CE **ahead** of EE, so the sync is no longer a no-op — see **CE→EE sync:
required resolution** below for the exact steps.

### Architecture

**Server** — follows the existing `controller → ce service →
ce_compatible → ee override` layering, all in `ce` packages:

- `AIConfigControllerCE` / `AIConfigController` for `/ai-config`
(`test-connection`, `fetch-models`, `test-api-key`), each gated on
`MANAGE_ORGANIZATION`
- `AIConfigServiceCE(Impl)`, `AIAssistantServiceCE(Impl)`,
`AIReferenceServiceCE(Impl)` with their `ee` override points and
`AIConfigServiceCECompatible(Impl)`
- `AIAssistantConfig` on `OrganizationConfiguration`, `Migration075`,
and the `AIProvider` / DTO types
- `POST /users/ai-assistant/request` on `UserControllerCE`
- `ai-references/*.md` prompt-reference resources

**Client** — the implementation moves from `src/ee` into `src/ce`, which
is where a CE-owned feature belongs. This is safe because the EE UI
files import nothing EE-only; every import is a package, a shared path,
or an `ee/` alias that resolves through CE's shims. The existing
`src/ee` shims from #41692 are untouched and now re-export real code
instead of stubs, and the exported symbol surface of every relocated
file is unchanged. The AI reducer and saga are registered in
`ce/reducers` and `ce/sagas` rather than their `ee` counterparts, and
the admin AI settings page is registered for superusers.

**This PR adds no `src/ee` files**, because the CE pre-push architecture
guard rejects them. Four CE-owned modules therefore have no `ee` shim to
import through — `aiAssistantReducer`, `AIAssistantSagas`, `GPT/shared`,
and the admin AI config — so they are imported from `ce/` directly, each
with a documented `eslint-disable` for `no-restricted-imports`. That is
the same accommodation the native Custom Widget copilot uses in #42063.
If EE would rather route these through `ee/` shims, those shims belong
in a companion EE PR.

Adds `react-markdown` and `remark-gfm`, used by the assistant's response
renderer.

### Impact on existing instances

Inert by default. `AIAssistantConfig` is absent until an admin
configures a provider, `isAIAssistantEnabled` defaults to false, and
`Migration075` only adds the field. With nothing configured, the Ask AI
affordances stay hidden exactly as they do today — no feature flag is
involved, matching how EE ships it since #9119.

### Security fixes included

A nine-reviewer council on the ported code surfaced four defects. All
four are inherited byte-identical from EE and are therefore **live in EE
production today**; because EE's `AIConfigServiceImpl` delegates every
method to the CE class and `AIAssistantServiceImpl` overrides nothing,
fixing them here carries them into EE through the sync rather than
needing a parallel EE change.

1. **SSRF, two call sites.** `callLocalLLMAPI` built a raw `WebClient`,
bypassing `WebClientUtils` and substituting a check that tested only
`isLinkLocalAddress` on the first resolved address — missing loopback,
and racy. `callAzureOpenAIAPI` chained `.clientConnector(...)` *after*
`WebClientUtils.builder()`, which replaces the connector carrying the
DNS-aware resolver; it read as protected and was not. Both now build
through `WebClientUtils.builder(httpClient)`.
2. **`getAIConfig` authorization.** It was the only one of five service
methods without `MANAGE_ORGANIZATION`, disclosing `localLlmUrl`,
`azureOpenaiEndpoint` and the deployment name to any authenticated user,
on every session. Managers still get the full configuration; everyone
else gets enablement, provider, and credential-presence booleans —
exactly what the client consumes.
3. **API keys stored in cleartext.** The `@Encrypted` annotations never
applied — the traversal only descends into `AppsmithDomain` types, and
the write is a sparse `updateById` so the encrypting lifecycle listener
never fires. `AIConfigSecretsCE` now encrypts and decrypts at the few
write/read points, and `Migration076` encrypts existing values in place,
idempotently.
4. **Admin key field corrupted credentials.** A stored key loaded into
the input as the literal `••••••••` with a save guard comparing against
that mask, so typing without clearing persisted `••••••••sk-…` behind a
success toast.

**Behaviour change worth calling out:** a local-LLM URL pointing at
loopback is now refused. In the single-container CE deployment
`127.0.0.1` is Mongo, Redis and RTS rather than the operator's Ollama —
which is the reason to refuse it. A local model on another host or
container stays reachable by hostname or private IP. This also makes the
runtime path agree with `/ai-config/test-connection`, which already went
through `WebClientUtils`.

### Follow-ups (tracked, not addressed here)

1. **Unmetered LLM spend** — `/users/ai-assistant/request` has no rate
limit or per-user quota; on an open-signup CE instance any account can
drain the admin's provider billing.
2. **OpenAI provider lacks guards the others have** — no
empty/max-length prompt validation and no `max_tokens`.
3. **`/users/ai-assistant/request` maps every failure to 400**,
including upstream timeouts, which hurts monitoring.
4. **A measured 0.5–1.0 s reactive-thread stall** in
`AiDatasourceSchemaSerializerCE.extractReferencedTableNames` at the
DTO's own size ceilings.
5. **Dead code carried from EE** — `AIWindow` and the in-editor
`AISidePanel` have no importer, and `ce/utils/aiSchemaSerializer.ts` has
no consumer but its own test.
6. **Test coverage** — `AIConfigSecretsCE` and `Migration076` both route
through `EncryptionHelper`, whose static initialiser needs
`APPSMITH_ENCRYPTION_PASSWORD`/`SALT`. Those are set for the
integration-test and Docker CI jobs but not for `server-unit-tests`, so
this coverage belongs in the integration suite.

A follow-up in `appsmith-ee` should reduce EE's `src/ee` Ask AI files to
re-export shims and drop its `ee/reducers` + `ee/sagas` registration, so
EE consumes this CE implementation instead of shadowing it.

https://linear.app/appsmith/issue/APP-15737

Supersedes the original, stale-closed CE attempt in #41590.

## Automation

/ok-to-test tags="@tag.All"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/30836147916>
> Commit: deab697
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=30836147916&attempt=2"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.All`
> Spec:
> <hr>Mon, 03 Aug 2026 18:47:45 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [x] Yes
- [ ] No

Ask AI becoming available in the community edition is a user-facing
change worth announcing.



## CE→EE sync: required resolution

**This section is load-bearing. The sync of this PR is not a no-op, and
two of its failure modes arrive through *clean* merges — no conflict
marker will surface them.** Whoever runs the sync should follow this,
and it is the condition the architecture review set for unblocking.

Of the changed files that also exist in EE, **18 differ from EE's
copy**. Most are the deliberate hardening in the security commit, which
moves CE ahead of EE on purpose. Five are add/add conflicts
(`ce/sagas/AIAssistantSagas.ts`, `ce/pages/AdminSettings/config/ai.tsx`,
`pages/AdminSettings/AI/index.tsx`, `AIAssistantServiceCEImpl.java`,
`AIConfigServiceCEImpl.java`).

> **These steps are for the sync itself. None of them can be pre-landed
in EE as a separate PR — verified against `appsmith-ee/origin/release`
(`0aff44fa56`, "Sync community release"):**
>
> - **The saga.** EE's `ce/sagas/index.tsx` does **not** register the AI
saga yet — only `ee/sagas/index.tsx` does. Removing EE's registration
*before* the CE change syncs would leave zero registrations and take Ask
AI out of EE entirely. It is only safe once CE's registration has
arrived.
> - **The enum.** EE's `ASK_AI_ORG_CONFIG_UPDATED` /
`ASK_AI_ORG_TEST_RUN` are referenced by `AIConfigServiceCEImpl` (lines
172-173, 236) and its test. Deleting them ahead of the sync breaks EE's
compile. This is a conflict *resolution*, not a change that exists
independently.
>
> So this is work for whoever runs the sync, in the same merge — not a
companion PR that can land first.

### 1. Remove EE's now-duplicate saga registration

CE now registers the AI saga itself, and that CE file merges **cleanly**
into EE — so EE ends up registering it twice:

| EE file | What to do |
|---|---|
| `app/client/src/ee/sagas/index.tsx` | **Remove** the
`aiAssistantSagas` import (from `ee/sagas/AIAssistantSagas`, a shim that
re-exports `ce/sagas/AIAssistantSagas`) and its entry in the saga array
— CE's registration now covers EE |

Left as-is, EE runs the *same* watcher generator twice, so every Ask AI
action fires duplicate requests to the provider — double latency and
double spend.

This one genuinely needs an EE change: EE builds `sagasArr` as
`[...CE_Sagas, …, aiAssistantSagas]`, appending its own entry *after*
spreading CE's list, so CE cannot deduplicate it from its side.

**The duplicate admin category no longer needs an EE change.**
`ConfigFactory.register` is CE-owned and was a raw push into three
collections (`categories`, `settings`, `savableCategories` — only
`settingsMap` was keyed and therefore safe). It is now idempotent, so a
category registered from both `ce/` and `ee/` collapses to one entry on
its own. EE's `ConfigFactory.register(AIConfig)` can stay exactly as it
is.

### 2. Resolve the five add/add conflicts toward CE, wholesale

`Migration076EncryptAIAssistantApiKeys` merges cleanly and will encrypt
EE's stored keys on first boot. EE's current `AIAssistantServiceCEImpl`
/ `AIConfigServiceCEImpl` read those keys **without**
`AIConfigSecretsCE.decrypt`. If either file is resolved toward EE's
copy, **EE sends ciphertext as its `Authorization` header and Ask AI
breaks in EE**.

`pages/AdminSettings/AI/index.tsx` must also move together with
`AIConfigServiceCEImpl` — the client's `hasStoredX` model depends on the
server's `has*` response shape and the manager-only full config.

### 3. Collapse the duplicated analytics enum

`AnalyticsEvents.java`: CE adds `ASK_AI_ORG_CONFIG_UPDATED` /
`ASK_AI_ORG_TEST_RUN` at the enum tail (lines 106/109); EE already has
both at lines 140/143. Naive resolution produces duplicate enum
constants and **fails to compile**. Keep one pair.

### Correction to an earlier claim in this description

An earlier revision said porting from EE keeps the two editions
"byte-identical on the `ce`-package files, so the sync stays a no-op".
That was true of the initial port and is **no longer true**: the
security commit, and the review fixes on top of it, deliberately move CE
ahead. The byte-identity argument still holds for the ~40 untouched
ported files and for the reason to port rather than revive
`feat/enable-ai`, but the sync itself needs the three steps above.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added Ask AI assistance for JavaScript, SQL, GraphQL, and JSON
editing.
* Added resizable chat panels with conversation history, editor context,
Markdown responses, quick actions, and keyboard shortcuts.
* Added a global AI assistant panel with context-aware prompts and
schema support.
* Added administrator settings for Claude, OpenAI, Azure OpenAI, and
local Ollama-compatible providers.
* Added connection, credential, and model testing with secure credential
handling and request safeguards.
* **Documentation**
* Added reference guides for JavaScript, SQL, GraphQL, and common
troubleshooting scenarios.
* **Tests**
  * Added coverage for schema handling and AI configuration workflows.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Enhancement New feature or request Stale

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants